//**********************************   *****************************//
//***********************************Radioaktiv.ru************************************//
// CodeVisionAVR
//   reset disable, 
//       
#include <tiny13a.h>
#define F_CPU 1200000UL
#include <delay.h>

//  
int bat_volt_min = 535;//  
//  
bit lcd_on=0; //-     
//(        power)
bit bp=0;  //-    power    
bit power_button=0; //-      ,  
//  (   )
bit first_start=0;  //-     (  
//   power)
bit batt_bad=0; //-  
bit power_on=0; //-  ,  
bit HUB_state=0; //-  ,  , 
//  ( -,   power_on)
unsigned int timer0_sec=0; //   
unsigned int timer0_count=0; // 
unsigned int batt_volt=0; //       

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
    timer0_count++;
     if (timer0_count==146)
     {
       timer0_sec+=1;
      timer0_count=0;
       }
}
// Bandgap Voltage Reference: Off
#define ADC_VREF_TYPE ((0<<REFS0) | (0<<ADLAR))
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=(1<<ADSC);
// Wait for the AD conversion to complete
while ((ADCSRA & (1<<ADIF))==0);
ADCSRA|=(1<<ADIF);
return ADCW;
}
//    
void all_off ()
    {
       PORTB.4=1;
       HUB_state=0;
       PORTB.0=HUB_state;
       first_start=0;
       power_on=0;
       lcd_on=0;
       bp=0;
       power_button=0;
    }  
//    Power  
void power_on_off ()
    {
    if (lcd_on==0)
    {
    PORTB.1=1;
    delay_ms (300);
    PORTB.1=0; 
    } 
    else lcd_on=0;
    HUB_state=!HUB_state;
    PORTB.0=HUB_state;
    power_on=!power_on;    
    } 
//  
void check_bat ()
    { 
    batt_volt = read_adc (1); 
    if (batt_volt < bat_volt_min)
     {
     batt_bad=1;
     }
    else {
     batt_bad=0;
         };                        
    }
//    
void first_start_func ()
    {
      check_bat ();  
      if (batt_bad==1)
        {
         all_off ();
        } 
      if (PINB.3==1 && PINB.5==0 && batt_volt>=bat_volt_min)
        {
        PORTB.4=0;
        HUB_state=1;
        PORTB.0=HUB_state;
        first_start=1;
        power_on=1;
        PORTB.1=1;
        delay_ms (1000);
        PORTB.1=0;        
        }  
      timer0_count=0;
      timer0_sec=0;     
    }
//    
void first_start_func_pw ()
    {
      check_bat ();  
      if (batt_bad==1)
        {
         all_off ();
        } 
      if (PINB.3==0 && PINB.5==1 && batt_volt>=bat_volt_min)
        {
        PORTB.4=0;
        HUB_state=1;
        PORTB.0=HUB_state;
        first_start=1;
        power_on=1;
        PORTB.1=1;
        delay_ms (1000);
        PORTB.1=0;
        power_button=1;        
        }  
      timer0_count=0;
      timer0_sec=0;     
    }           
//      
void power_click ()
    {
    if (power_on == 0 && first_start==1 && PINB.3==0 && PINB.5==1 && bp==0 && batt_volt>=bat_volt_min)
    {
    bp=1;
    PORTB.1=1;
    HUB_state=1;
    PORTB.0=HUB_state;
    delay_ms (300);
    PORTB.1=0;
    power_on=1; 
    power_button=1;
    timer0_sec=0;                   
    }
    if (power_on == 1 && first_start==1 && PINB.5==1 && bp==0)
    {
    bp=1;
    PORTB.1=1;
    delay_ms (300);
    PORTB.1=0; 
    lcd_on=!lcd_on;
        if (lcd_on==0) timer0_sec=0;
    } 
    if (PINB.5==0)
    {
    bp=0;
    } 
    }              
 
void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=(1<<CLKPCE);
CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Function: Bit5=In Bit4=Out Bit3=In Bit2=In Bit1=Out Bit0=Out 
DDRB=(0<<DDB5) | (1<<DDB4) | (0<<DDB3) | (0<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit5=T Bit4=1 Bit3=T Bit2=T Bit1=0 Bit0=0 
PINB=(0<<PINB5) | (1<<PINB4) | (0<<PINB3) | (0<<PINB2) | (0<<PINB1) | (0<<PINB0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 37,500 kHz
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
// Timer Period: 6,8267 ms
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (1<<TOIE0);

// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
GIMSK=(0<<INT0) | (0<<PCIE);
MCUCR=(0<<ISC01) | (0<<ISC00);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIS1) | (0<<ACIS0);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR0=(0<<AIN0D) | (0<<AIN1D);

// ADC initialization
// ADC Clock frequency: 600,000 kHz
// ADC Bandgap Voltage Reference: Off
// ADC Auto Trigger Source: ADC Stopped
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
DIDR0|=(0<<ADC0D) | (0<<ADC2D) | (0<<ADC3D) | (0<<ADC1D);
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);


// Global enable interrupts
#asm("sei")
while (1)
      {  
      power_click ();
      if (first_start==0)
        {
         first_start_func ();
         first_start_func_pw ();
        }
       if (PINB.3==0 && timer0_sec>=5 && power_on==1 && power_button==0)
        {
         power_on_off ();   
        }    
       if (PINB.3==0 && timer0_sec>=10 && power_on==1 && power_button==1)
        {
         power_on_off ();
         power_button=0;   
        }  
       if (PINB.3==0  && timer0_sec>=1)
         {
         check_bat ();
         }  
      if (batt_bad==1)
        {
         all_off ();
        } 
      if (PINB.3==0 && timer0_sec>=50) 
        {
         all_off ();   
        }  
      if (PINB.3==1 && power_on==0 && batt_bad==0 && first_start==1)
        {
         power_on_off ();
         timer0_sec=0;
        } 
      if (PINB.3==1 && power_on==1)
        {
        timer0_sec=0;    
        }
      }
}